home *** CD-ROM | disk | FTP | other *** search
/ Nebula 2 / Nebula Two.iso / SourceCode / Twin / EvalDelegate.m < prev    next >
Text File  |  1995-06-12  |  8KB  |  283 lines

  1.  
  2. /* Generated by Interface Builder */
  3.  
  4. static char copyright[] = "Copyright 1990 by The MITRE Corporation.";
  5. /* John D. Ramsdell - June 1990
  6.  *
  7.  * Copyright 1990 by The MITRE Corporation
  8.  *
  9.  * This program is free software; you can redistribute it and/or modify
  10.  * it under the terms of the GNU General Public License as published by
  11.  * the Free Software Foundation; either version 1, or (at your option)
  12.  * any later version.
  13.  *
  14.  * This program is distributed in the hope that it will be useful,
  15.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  17.  * GNU General Public License for more details.
  18.  * 
  19.  * You should have received a copy of the GNU General Public License
  20.  * along with this program; if not, write to the Free Software
  21.  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  22.  */
  23.  
  24. /* 
  25.  * MAXHISTORYTEXT gives the maximum amount of text allowed in the history 
  26.  * text window.  When the limit is exceeded, the first MAXHISTORYTEXT/2
  27.  * characters are deleted.
  28. */
  29.  
  30. #if !defined MAXHISTORYTEXT
  31. #define MAXHISTORYTEXT (1 << 18)
  32. #endif
  33.  
  34. #import "EvalDelegate.h"
  35. #import "EvalListener.h"
  36. #import "startSlaveProcess.h"
  37. #import <appkit/Application.h>
  38. #import <appkit/Font.h>
  39. #import <defaults/defaults.h>
  40. #import <appkit/appkit.h>
  41. #import <appkit/ScrollView.h>
  42. #import <appkit/Text.h>
  43. #import <stdio.h>
  44. #import <stdlib.h>
  45. #import <string.h>
  46.   
  47. static NXCharFilterFunc defaultEditorFilter;
  48.  
  49. /* This makes the inputText view end input when ENTER is typed. */
  50. #define NX_ENTER 3
  51. static unsigned short 
  52. inputEditorFilter(unsigned short theChar, int flags, unsigned short charSet)
  53. {
  54.   if (flags & NX_COMMANDMASK) return 0;
  55.   if (theChar == NX_ENTER) return NX_RETURN;
  56.   return (*defaultEditorFilter) (theChar, flags, charSet);
  57. }   
  58.  
  59. FILE *processOut;        /* Place to write to the slave process. */
  60.  
  61. @implementation EvalDelegate
  62.   
  63. void startEvalListener(EvalDelegate *evalDelegate)
  64. {
  65.   EvalListener *evalListener;    /* Start listener for remote messages. */
  66.   evalListener = [EvalListener new];
  67.   [evalListener setDelegate:evalDelegate];
  68.   [evalListener checkInAs:"Twin"];
  69.   [evalListener addPort];
  70. }
  71.  
  72. Font *getFont(void)
  73. {
  74.   const char *fontname;
  75.   float fontsize;
  76.   
  77.   static NXDefaultsVector twinDefaults = {
  78.     {"SlaveCommand", "t"},
  79.     {"Columns", "80"},
  80.     {"NXFixedPitchFont", "Ohlfs"},
  81.     {"NXFixedPitchFontSize", "10.0" },
  82.     {NULL}
  83.   };
  84.   NXRegisterDefaults("Twin", twinDefaults);
  85.  
  86.   fontname = NXGetDefaultValue("Twin", "NXFixedPitchFont");
  87.   fontsize = atof(NXGetDefaultValue("Twin", "NXFixedPitchFontSize"));
  88.  
  89.   return [Font newFont:fontname size:fontsize];
  90. }
  91.  
  92. - setHistoryScrollView:anObject
  93. {
  94.   NXCoord widthInChars;
  95.   NXRect historyRect, windowRect;
  96.   id window;
  97.   NXCoord width;
  98.   
  99.   historyScrollView = anObject;
  100.   historyText = [historyScrollView docView];
  101.  
  102.   displayFont = getFont();
  103.  
  104.   /* Set width of windows. */
  105.   widthInChars = atoi(NXGetDefaultValue("Twin", "Columns"));
  106.   if (widthInChars < 20.0) widthInChars = 20.0;
  107.   width = widthInChars
  108.     * ([displayFont getWidthOf:"  "] - [displayFont getWidthOf:" "]);
  109.   [historyText getFrame:&historyRect];
  110.   window = [historyText window];
  111.   [window getFrame:&windowRect];
  112.   width += NX_WIDTH(&windowRect) - NX_WIDTH(&historyRect);
  113.   [window sizeWindow:width :NX_HEIGHT(&windowRect)];
  114.  
  115.   [historyText setFont:displayFont];
  116.   startEvalListener(self);
  117.  
  118.   return self;
  119. }
  120.  
  121. - setInputScrollView:anObject
  122. {
  123.   inputScrollView = anObject;
  124.   inputText = [inputScrollView docView];
  125.   defaultEditorFilter = [inputText charFilter];
  126.   [inputText setCharFilter:inputEditorFilter];
  127.   [inputText setDelegate:self];
  128.   return self;            /* Font set in appDidInit. */
  129. }
  130.  
  131. static BOOL stringVisibleMode = TRUE;
  132.  
  133. - toggleStringVisibleMode:sender
  134. {
  135.   stringVisibleMode = !stringVisibleMode;
  136.   return self;
  137. }
  138.  
  139. void selectEnd(id text)
  140. {
  141.   int length;
  142.   length = [text textLength];
  143.   [text setSel:length :length];
  144. }
  145.  
  146. - showString:(char *)string    /* Add text to history view. */
  147. {
  148.   int length;
  149.   length = [historyText textLength];
  150.   if (length >= MAXHISTORYTEXT) {
  151.     [historyText setSel:0 :(MAXHISTORYTEXT>>1)-1];
  152.     [historyText setEditable:YES];
  153.     [historyText delete:self];    /* Delete first half of text. */
  154.     return [self showString:string]; /* Try again. */
  155.   }
  156.   [historyText setSel:length :length];
  157.   [historyText setEditable:YES];
  158.   [historyText replaceSel:string];
  159.   [historyText setEditable:NO];
  160.   if (stringVisibleMode) [historyText scrollSelToVisible];
  161.   selectEnd(inputText);
  162.   return self;
  163. }
  164.  
  165. - sendString:(char *)string    /* Send string to the slave process. */
  166. {
  167.   if (EOF == fputs(string, processOut)) {
  168.     fprintf(stderr, "\nCannot write.\n");
  169.     [NXApp terminate:self];
  170.   }
  171.   fflush(processOut);
  172.   return self;
  173. }
  174.  
  175. - showPasteboard:sender        /* Copy pasteboard to history view. */
  176. {
  177.   int length;
  178.   length = [historyText textLength];
  179.   if (length >= MAXHISTORYTEXT) {
  180.     [historyText setSel:0 :(MAXHISTORYTEXT>>1)-1];
  181.     [historyText setEditable:YES];
  182.     [historyText delete:self];    /* Delete first half of text. */
  183.     return [self showPasteboard:sender]; /* Try again. */
  184.   }
  185.   [historyText setSel:length :length];
  186.   [historyText setEditable:YES];
  187.   [historyText paste:self];
  188.   [historyText setEditable:NO];
  189.   selectEnd(inputText);
  190.   return self;
  191. }
  192.  
  193. - evalPasteboard:sender        /* Copy pasteboard to history view */
  194. {                /* and send text to the slave process. */
  195.   int stringStart, stringLength;
  196.   char *textBuffer;
  197.   stringStart = [historyText textLength];
  198.   [self showPasteboard:self];
  199.   stringLength = [historyText textLength] - stringStart + 1;
  200.   textBuffer = malloc(stringLength);
  201.   [historyText getSubstring:textBuffer start:stringStart length:stringLength];
  202.   [self sendString:textBuffer];
  203.   free (textBuffer);
  204.   return self;
  205. }
  206.  
  207. - evalSelection:sender        /* Evaluate the selection in the */
  208. {                /* history view. */
  209.   NXSelPt selStart, selEnd; int selLength;
  210.   
  211.   if ([[[historyText window] firstResponder] isDescendantOf:historyText]) {
  212.     /* getSel fails unless historyText is in the responder's view chain. */
  213.     [historyText getSel:&selStart :&selEnd];
  214.     selLength = selEnd.cp - selStart.cp;
  215.  
  216.     if (selLength > 0) {
  217.       [historyText copy:self];
  218.       return [self evalPasteboard:self];
  219.     }
  220.   }
  221.   NXBeep();            /* Beep on failure. */
  222.   return self;
  223. }
  224.  
  225. - evalInput:sender        /* Cut text from input view into */
  226. {                /* the pasteboard and perform */
  227.   int length;            /* evalPasteboard. */
  228.   length = [inputText textLength];
  229.   if (length > 0) {
  230.     [inputText setSel:length :length];
  231.     [inputText replaceSel:"\n"]; /* Add a return. */
  232.     [inputText selectAll:self];
  233.     [inputText cut:self];
  234.     return [self evalPasteboard:self];
  235.   }
  236.   [inputText selectAll:self];
  237.   return self;
  238.  
  239. - sendInterrupt:sender
  240. {
  241.   (void) interruptSlaveProcess();
  242.   return self;
  243. }
  244.  
  245. /* As a listener delegate. */
  246.  
  247. - (int)evalString:(char *)string /* Copies string to historyText */
  248. {                /* and then sends string to slave. */
  249.   [self showString:string];    /* Used to respond to a remote message. */
  250.   [self sendString:string];
  251.   return 0;            /* Signal success. */
  252. }
  253.  
  254. /* As an application delegate. */
  255.  
  256. - appDidInit:sender
  257. {
  258.   [inputText setFont:displayFont];
  259.   [[inputText window] makeKeyAndOrderFront:self];
  260.   [inputText selectAll:self];
  261.   processOut = startSlaveProcess(self);
  262.   return self;
  263. }
  264.  
  265. - appDidBecomeActive:sender
  266. {
  267.   [[inputText window] makeKeyAndOrderFront:self];
  268.   return self;
  269. }
  270.  
  271. /* As a Text delegate. */
  272.  
  273. - textDidEnd:sender endChar:(unsigned short)whyEnd
  274. {
  275.   if (whyEnd == NX_RETURN)
  276.     return [self evalInput:self];
  277.   else
  278.     return self;
  279. }
  280.  
  281. @end
  282.